package com.xander.socketserver.server;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * @author 叶振东
 * @date 2019-01-21
 */
@ServerEndpoint("/websocket/{username}")
@Component
public class SocketServer {
    private static ConcurrentHashMap<String, SocketServer> userPools = new ConcurrentHashMap<>();

    private Session session;

    private String username;

    /**
     * 连接成功调用的方法
     * @param username
     * @param session
     * @return void
     * @author yezhendong
     * @date 2019-01-21
     */
    @OnOpen
    public void onOpen(@PathParam("username") String username, Session session) throws UnsupportedEncodingException {
        //用户名转换成UTF-8编码防止乱码
        username = new String(username.getBytes("ISO-8859-1"),"UTF-8");
        this.username = username;
        this.session = session;
        //加入用户池中
        userPools.put(username, this);
        System.out.println("有新连接加入！当前在线人数为" + userPools.size());
        sendLoginUser();
    }

    /**
     * 连接关闭调用的方法
     * @param
     * @return void
     * @author yezhendong
     * @date 2019-01-21
     */
    @OnClose
    public void onClose() {
        //从用户池中删除
        userPools.remove(username);
        sendLoginUser();
        System.out.println("有一连接关闭！当前在线人数为" + userPools.size());
    }

    /**
     * 收到客户端消息后调用的方法（所有操作都在这里执行）
     * @param message
     * @return void
     * @author yezhendong
     * @date 2019-01-21
     */
    @OnMessage
    public void onMessage(String message) {
        //消息转换为JSON
        JSONObject jsonObject = JSON.parseObject(message);
        //请求编号 1为私聊 0为发送所有人
        String code = jsonObject.getString("code");
        //发给谁
        String toUsername = jsonObject.getString("username");
        //发送的消息
        String text = jsonObject.getString("message");
        System.out.println("来自客户端的消息:" + text);
        switch (code) {
            case "0": {
                //群发消息
                for (String key : userPools.keySet()) {
                    try {
                        userPools.get(key).sendMessage(1, username + "(群聊)说：" + text);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            break;
            case "1": {
                //给指定用户发消息
                try {
                    userPools.get(username).sendMessage(1, username + "(私聊)说：" + text);
                    userPools.get(toUsername).sendMessage(1, username + "(私聊)说：" + text);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            break;
            //禁言（强制断开连接）
            case "3":{
                try {
                    userPools.get(toUsername).sendMessage(1,  "<h1 style='color:red'>系统：您已被禁言！</h1>");
                } catch (IOException e) {
                    e.printStackTrace();
                }
                userPools.remove(toUsername);
            }
            break;
            default:break;
        }


    }

    /**
     * 发生错误时调用的方法
     * @param session
     * @param error
     * @return void
     * @author yezhendong
     * @date 2019-01-21
     */
    @OnError
    public void onError(Session session, Throwable error) {
        System.out.println("发生错误");
        error.printStackTrace();
    }


    /**
     * 发送消息
     * @param code
     * @param message
     * @return void
     * @author yezhendong
     * @date 2019-01-21
     */
    public void sendMessage(int code, Object message) throws IOException {
        JSONObject result = new JSONObject();
        //1为正常发消息 0为发送用户列表
        result.put("code", code);
        result.put("message", message);
        this.session.getBasicRemote().sendText(result.toString());
        //this.session.getAsyncRemote().sendText(message);
    }

    /**
     * 发送用户池中的登录用户列表
     *
     * @param
     * @return void
     * @author yezhendong
     * @date 2019-01-21
     */
    public void sendLoginUser() {
        CopyOnWriteArraySet<String> users = new CopyOnWriteArraySet<>(userPools.keySet());
        users.remove("admin");
        for (String key : userPools.keySet()) {
            try {
                userPools.get(key).sendMessage(0, users);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        //this.session.getAsyncRemote().sendText(message);
    }

    /**
     * 群发自定义消息方法
     * @param message
     * @return void
     * @author yezhendong
     * @date 2019-01-21
     */
    public static void sendInfo(String message) throws IOException {
        for (String key : userPools.keySet()) {
            try {
                userPools.get(key).sendMessage(1, message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
